/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.diagram.composite.editpart;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.gef.EditPart;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.uml2.uml.Connector;

import com.cea.papyrus.core.editor.ModelManager;
import com.cea.papyrus.core.editpart.GraphEdgeEditPart;
import com.cea.papyrus.core.editpart.StereotypeDisplayEditPart;
import com.cea.papyrus.core.figures.MiddleEndpointLocator;
import com.cea.papyrus.diagram.composite.figure.ConnectorFigure;
import com.cea.papyrus.diagraminterchange2.di2.GraphEdge;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;
import com.cea.papyrus.diagraminterchange2.di2.Uml1SemanticModelBridge;

/**
 * Controller for a {@link Connector}
 */
public class ConnectorEditPart extends GraphEdgeEditPart implements PropertyChangeListener {

	/**
	 * The selected.
	 */
	protected boolean selected;

	/**
	 * The property source.
	 */
	protected IPropertySource propertySource = null;

	/**
	 * The the name label.
	 */
	protected ConnectorNameEditPart theNameLabel; 

	/**
	 * The the stereotype label.
	 */
	protected StereotypeDisplayEditPart theStereotypeLabel; 

	/**
	 * Creates a new ConnectorEditPart
	 * @param graphEdge the graph edge representing the connector
	 * @param modelManager the model manager associated to the editor
	 */
	public ConnectorEditPart(GraphEdge graphEdge,ModelManager modelManager) {
		super(graphEdge,modelManager);
		//label of the name of the Dependency
		this.theNameLabel =new ConnectorNameEditPart(
				(GraphNode)this.getGraphEdge().getContained().get(0),
				this.getUmlElement(),
				modelManager);
		this.theStereotypeLabel=new StereotypeDisplayEditPart(
				(GraphNode)this.getGraphEdge().getContained().get(1),
				this.getUmlElement(),
				modelManager,
				this);
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.editpart.GraphEdgeEditPart#createEditPolicies()
	 */
	@Override
	protected void createEditPolicies() {
		super.createEditPolicies();
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.editpart.GraphEdgeEditPart#propertyChange(java.beans.PropertyChangeEvent)
	 */
	@Override
	public void propertyChange(PropertyChangeEvent event) {
		//refreshVisuals();
		this.refreshBendpoints();
	}


	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.editpart.GraphEdgeEditPart#createFigure()
	 */
	@Override
	protected IFigure createFigure() {
		return new ConnectorFigure();
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.editpart.GraphEdgeEditPart#getUmlElement()
	 */
	@Override
	public Connector getUmlElement() {
		return (Connector)((Uml1SemanticModelBridge)this.getGraphEdge().getSemanticModel()).getElement();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.editparts.AbstractEditPart#getModelChildren()
	 */
	@Override
	protected List getModelChildren() {
		ArrayList contained= new ArrayList();
		Iterator it=this.getGraphEdge().getContained().iterator();
		while (it.hasNext()){
			GraphElement ge=(GraphElement)it.next(); //getOnly graphNode
			if (!(ge instanceof GraphEdge)){
				contained.add(ge);
			}
		}
		return contained;

	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.editparts.AbstractEditPart#createChild(java.lang.Object)
	 */
	@Override
	protected EditPart createChild(Object model) {
		if( model instanceof GraphNode) {
			//first graphNode= name of the dependency
			if( ((GraphNode)model) == ((GraphNode)this.getGraphEdge().getContained().get(0)) ) {
				return this.theNameLabel;
			} else if( ((GraphNode)model) == ((GraphNode)this.getGraphEdge().getContained().get(1)) ) {
				return this.theStereotypeLabel;
			}

			throw new RuntimeException("unknown model list");
		}
		return super.createChild(model);
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.editpart.GraphEdgeEditPart#refreshVisuals()
	 */
	@Override
	protected void refreshVisuals() {
		//refresh figure
		super.refreshVisuals();

		//refresh name
		this.theNameLabel.refresh();
		this.theStereotypeLabel.refresh();
		//calculate middle point of the label
		org.eclipse.draw2d.geometry.Point middleLabel =new org.eclipse.draw2d.geometry.Point(
				this.theNameLabel.getGraphNode().getPosition().x-((Label) this.theNameLabel.getFigure()).getPreferredSize().width/2,
				this.theNameLabel.getGraphNode().getPosition().y-((Label) this.theNameLabel.getFigure()).getPreferredSize().height/2
		);
		//caluclate middle point of the link
		MiddleEndpointLocator lo =new MiddleEndpointLocator ((PolylineConnection)this.getFigure(),
				middleLabel);

		IFigure f=this.theNameLabel.getFigure();
		f.setLocation(this.theNameLabel.getGraphNode().getPosition());//set lael a the good position
		if (this.theNameLabel.isVisible()){
			this.getContentPane().getLayoutManager().setConstraint(this.theNameLabel.getFigure(),lo);
		}

		//calculate middle point of the stereotype label
		middleLabel =new org.eclipse.draw2d.geometry.Point(
				this.theStereotypeLabel.getGraphNode().getPosition().x-((Label) this.theStereotypeLabel.getFigure()).getPreferredSize().width/2,
				this.theStereotypeLabel.getGraphNode().getPosition().y-((Label) this.theStereotypeLabel.getFigure()).getPreferredSize().height/2
		);
		//caluclate middle point of the link
		lo =new MiddleEndpointLocator ((PolylineConnection)this.getFigure(),
				middleLabel);

		f=this.theStereotypeLabel.getFigure();
		f.setLocation(this.theStereotypeLabel.getGraphNode().getPosition());//set lael a the good position
		if (this.theStereotypeLabel.isVisible()){
			this.getContentPane().getLayoutManager().setConstraint(this.theStereotypeLabel.getFigure(),lo);
		}
	}

}